package com.swt.gap.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.swt.gap.common.PermissionService;
import com.swt.gap.common.constant.CommonConstant;
import com.swt.gap.common.PageResult;
import com.swt.gap.common.graph.Graph;
import com.swt.gap.config.ServerConfig;
import com.swt.gap.dao.TaskDao;
import com.swt.gap.dao.TaskResultMapper;
import com.swt.gap.model.entity.Task;
import com.swt.gap.model.entity.TaskResultWithBLOBs;
import com.swt.gap.model.graphmodel.UpdateTaskResultContentModel;
import com.swt.gap.model.vo.TaskResultUpdateVO;
import com.swt.gap.model.vo.TaskVO;
import com.swt.gap.model.vo.taskresult.AnalysisResultVO;
import com.swt.gap.model.vo.taskresult.TaskAndResult;
import com.swt.gap.model.vo.taskresult.TaskResultListVO;
import com.swt.gap.service.SysGroupService;
import com.swt.gap.service.TaskResultService;
import com.swt.gap.util.Base64ToImgUtil;
import com.swt.gap.util.TimeFormatUtil;
import com.swt.gap.util.UserLoginUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;

/**
 * @author tyh
 * @date 2020/5/8 15:50
 */

@Service
public class TaskResultServiceImpl implements TaskResultService {

    private final TaskResultMapper taskResultMapper;

    private final TaskDao taskDao;

    private final ServerConfig serverConfig;

    private final SysGroupService sysGroupService;
    private final PermissionService permissionService;

    public TaskResultServiceImpl(TaskResultMapper taskResultMapper, TaskDao taskDao,
                                 ServerConfig serverConfig,
                                 SysGroupService sysGroupService,
                                 PermissionService permissionService) {
        this.taskResultMapper = taskResultMapper;
        this.taskDao = taskDao;
        this.serverConfig = serverConfig;
        this.sysGroupService = sysGroupService;
        this.permissionService = permissionService;
    }


    @Override
    public Integer addTaskResult(TaskResultWithBLOBs taskResult) {
        String resultName = taskResult.getResultName();
        //判断是否重名，重名则加序号
        Boolean isRepeat = this.judgeResultName(resultName, null, taskResult.getTaskId());
        if(isRepeat){
            String newName = this.creatNewName(resultName, taskResult.getTaskId());
            taskResult.setResultName(newName);
        }
        Date date = new Date();
        taskResult.setCreatedTime(date);
        taskResult.setCreatedBy(UserLoginUtils.getUser().getUserId());
        taskResult.setIsDeleted(false);
        taskResult.setUpdateTime(date);

        String fileName = TimeFormatUtil.getCurrentTimeString() + "_" + taskResult.getResultName() + ".png";
        File dirFile = new File(CommonConstant.RESULT_PIC);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        String filePath = CommonConstant.RESULT_PIC + fileName;

        boolean success = Base64ToImgUtil.base64ToImg(taskResult.getPicSvg(), filePath);
        if (!success){
            return 0;
        }
        //String base64 = SvgUtils.svgParseBase64(taskResult.getPicSvg());

        taskResult.setPicSvg(fileName);

        return taskResultMapper.insertSelective(taskResult);
    }

    @Override
    public Integer deleteTaskResult(Integer resultId) {
        return taskResultMapper.deleteTaskResult(resultId);
    }

    @Override
    public Integer updateTaskResultInfo(TaskResultUpdateVO taskResultInfo) {
        TaskResultWithBLOBs taskResult = new TaskResultWithBLOBs();
        String resultName = taskResultInfo.getResultName();
        //判断是否重名，重名则加序号
        Boolean isRepeat = this.judgeResultName(resultName, taskResultInfo.getResultId(), taskResultInfo.getTaskId());
        if(isRepeat){
            String newName = this.creatNewName(resultName, taskResultInfo.getTaskId());
            taskResult.setResultName(newName);
        }else {
            taskResult.setResultName(taskResultInfo.getResultName());
        }
        taskResult.setUpdateTime(new Date());
        taskResult.setDescription(taskResultInfo.getDescription());
        taskResult.setResultId(taskResultInfo.getResultId());
        return taskResultMapper.updateByPrimaryKeySelective(taskResult);
    }

    @Override
    public Boolean judgeResultName(String resultName, Integer resultId, Integer taskId) {
        Integer userId = UserLoginUtils.getUserId();
        TaskResultWithBLOBs record = taskResultMapper.selectByResultName(resultName, userId, taskId);
        if(record == null){
            return false;
        }
        if(resultId != null){
            return !resultId.equals(record.getResultId());
        }
        return true;
    }

    @Override
    public String creatNewName(String resultName, Integer taskId) {
        //重名加序号
        String newName;
        Integer lastNum = taskResultMapper.LastSameNameIndex(taskId, resultName);
        if(lastNum == null){
            newName = resultName + "(" + 1 + ")";
        }else {
            lastNum += 1;
            newName = resultName + "(" + lastNum + ")";
        }

        return newName;
    }

    @Override
    public PageResult<TaskAndResult> getTaskResultByKeyword(Integer taskId, String keyword, Integer pageNum, Integer pageSize) {

        //分页
        if (null != pageNum && null != pageSize) {
            PageHelper.startPage(pageNum, pageSize);
        }
        Page<TaskAndResult> taskResultInfo = taskResultMapper.getTaskResultInfoByKeyword(taskId, keyword);
        //将图片路径遍历赋值到pic字段
        taskResultInfo.forEach(record -> {
            record.setPicSvg(serverConfig.parseViewUrl(record.getPicSvg(), 2));
            Set<String> fields = new HashSet<>();
            String content = record.getContent();
            List<Graph.Node> nodes = new ArrayList<>();
            switch (record.getType()) {
                case 1:
                    nodes = JSON.parseObject(content, Graph.class).getNodes();
                    break;
                case 2:
                    nodes = JSON.parseArray(content, Graph.Node.class);
                    break;
                default:
                    break;
            }
            nodes.forEach(node -> {
                if (node.getLabels().contains("事件")) {
                    fields.add("事件类型");
                } else {
                    fields.add(node.getLabels().get(1));
                }
            });
            record.setStatisticsFields(fields);
        });


        return new PageResult<>(taskResultInfo);
    }


    @Override
    public TaskResultWithBLOBs updateTaskResultContent(UpdateTaskResultContentModel updateTaskResultContentModel) {
        TaskResultWithBLOBs taskResults = taskResultMapper.selectByPrimaryKey(updateTaskResultContentModel.getResultId());

        String oldFilePath = CommonConstant.RESULT_PIC + taskResults.getPicSvg();
        String newFileName = TimeFormatUtil.getCurrentTimeString() + "_" + taskResults.getResultName() + ".png";
        String newFilePath = CommonConstant.RESULT_PIC + newFileName;
        boolean b = Base64ToImgUtil.base64ToImg(updateTaskResultContentModel.getPicSvg(), newFilePath);
        if (b){
            //删除旧图片
            File file = new File(oldFilePath);
            if (file.exists()){
                file.delete();
            }
        }
        taskResults.setContent(updateTaskResultContentModel.getContent());
        taskResults.setPicSvg(newFileName);
        taskResultMapper.updateByPrimaryKeySelective(taskResults);

        String newResultPicPath = serverConfig.parseViewUrl(newFileName, 2);
        taskResults.setPicSvg(newResultPicPath);

        return taskResults;
    }

    @Override
    public TaskResultWithBLOBs viewTaskResult(Integer resultId) {
        TaskResultWithBLOBs taskResult = taskResultMapper.selectByPrimaryKey(resultId);
        Optional.ofNullable(taskResult.getPicSvg()).ifPresent(pic -> {
            String newResultPicPath = serverConfig.parseViewUrl(taskResult.getPicSvg(), 2);
            taskResult.setPicSvg(newResultPicPath);
        });

        return taskResult;
    }

    @Override
    public TaskResultListVO getTaskResultList(Integer taskId) {
        TaskResultListVO taskResultListVO = new TaskResultListVO();
        taskResultListVO.setTaskId(taskId);
        List<TaskResultWithBLOBs> results = taskResultMapper.getResults(taskId);
        taskResultListVO.setTaskResultList(results);
        taskResultListVO.setCount(results.size());
        Task task = taskDao.selectByPrimaryKey(taskId);
        taskResultListVO.setStatus(task.getStatus());
        taskResultListVO.setTaskName(task.getTaskName());
        return taskResultListVO;
    }

    @Override
    public List<TaskResultListVO> listAccessTaskResult() {
        List<TaskResultListVO> res = new ArrayList<>();
        Integer loginUserId = UserLoginUtils.getUserId();
        List<Integer> userIds = sysGroupService.listSameGroupUserByUserId(loginUserId);
        Page<TaskVO> tasks = taskDao.getTaskByStatusAndGroup2(null, userIds, null);
        tasks.forEach(task -> {
            TaskResultListVO tr = new TaskResultListVO();
            BeanUtils.copyProperties(task, tr);
            tr.setHasReadPermission(permissionService.hasReadPerm(loginUserId, task.getCreatedBy(), task.getPassword()));

            List<TaskResultWithBLOBs> taskResults = taskResultMapper.getResults(task.getTaskId());
            taskResults.forEach(t -> t.setContent(""));
            tr.setTaskResultList(taskResults);
            res.add(tr);
        });
        return res;
    }

    @Override
    public PageResult<AnalysisResultVO> listAccessResult(Integer pageNum, Integer pageSize, String keyword, Integer userId) {
        List<Integer> userIds = sysGroupService.listSameGroupUserByUserId(userId);

        //分页
        if (null != pageNum && null != pageSize) {
            PageHelper.startPage(pageNum, pageSize);
        }
        Page<AnalysisResultVO> analysisResults = taskResultMapper.selectByUserIdAndKeyword(userIds, keyword);
        analysisResults.getResult().forEach(r -> {
            r.setHasReadPermission(permissionService.hasReadPerm(userId,
                    r.getCreatedBy(), r.getPassword()));
            r.setHasWritePermission(permissionService.hasWritePerm(userId, r.getCreatedBy()));
            r.setPicSvg(serverConfig.parseViewUrl(r.getPicSvg(), 2) );
        });

        return new PageResult<>(analysisResults);
    }

}
